package com.sinodata.bsm.cicp.collector.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.CommandReader;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: 带条件的正则匹配Shell采集器，当先满足条件的正则表达式后再进行正则表达式匹配。
 * Shell的输出只要有匹配一次条件后，后续的内容只要满足匹配正则表达式就当结果采集。
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * Jun 22, 2011 2:08:57 PM  liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class ConditionalRegexMatchShellCollector extends Collector {

    private static final Logger logger = Logger.getLogger(ConditionalRegexMatchShellCollector.class);

    /**
     *
     */
    public ConditionalRegexMatchShellCollector() {

    }

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        String cmd = this.paramMap.get("collectCmd");
        String conRegex = this.paramMap.get("conditRegex");
        String matchRegex = this.paramMap.get("matchRegex");
        BufferedReader reader = null;
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String[] propMetas = getPropMeta();
        try {
            reader = CommandReader.getReader(ip, cmd, (int) this.interval, 0);
            String readLine = null;
            boolean passed = false;
            Pattern pattern = Pattern.compile(conRegex);
            while ((readLine = reader.readLine()) != null) {
                Matcher matcher = pattern.matcher(readLine);
                if (!passed) {
                    if (matcher.find()) {
                        passed = true;
                        pattern = Pattern.compile(matchRegex);
                    }
                } else {
                    if (matcher.find()) {
                        ResPropertyValue propertyValueX = new ResPropertyValue();
                        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[matcher.groupCount()];
                        for (int i = 0; i < propValues.length; i++) {
                            propValues[i] = ResPropertyValue.createPropValue(matcher.group(i + 1), propMetas[i]);
                        }
                        propertyValueX.setValues(propValues);
                        values.add(propertyValueX);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("failed to collect by ConditionalRegexMatchShellCollector", e);
            throw new CollectorException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    logger.error("failed to close BufferedReader", e);
                }
            }
        }
        return values;
    }

    @Override
    public String[] getParamMeta() {
        // return new String[] { "collectCmd", "conditRegex", "matchRegex", "matchNum" };
        return new String[] { "collectCmd", "conditRegex", "matchRegex" };
    }

    @Override
    public String[] getPropMeta() {
        // int count = Integer.parseInt(this.paramMap.get("matchNum"));
        String regex = this.paramMap.get("matchRegex");
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher("");
        int count = matcher.groupCount();
        String[] propMetas = new String[count];
        for (int i = 1; i <= propMetas.length; i++) {
            propMetas[i - 1] = "$" + i;
        }
        return propMetas;
    }

    //	/**
    //	 * @param args
    //	 */
    //	public static void main(String[] args) {
    //		ConditionalRegexMatchShellCollector collector = new ConditionalRegexMatchShellCollector();
    //		collector.setInterval(10);
    //		Map paramMap = new HashedMap();
    //		paramMap.put("采集命令", "iostat -x");
    //		paramMap.put("条件正则表达式", "^ssd0\\s+.*");
    //		paramMap.put("匹配正则表达式", "^\\S+\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s*$");
    //		paramMap.put("匹配个数", "9");
    //		collector.setParamMap(paramMap);
    //		List<ResPropertyValueX> list = collector.collect("172.19.21.10");
    //		for (int i = 0; i < list.size(); i++) {
    //			System.out.println(list.get(i).toString());
    //		}
    //	}

}
